package dashboard.service;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.reflect.FieldUtils;

import com.bj58.argo.Argo;
import com.bj58.argo.logs.Logger;
import com.bj58.ecdata.dao.basedao.DAOHelper;

import dashboard.annotation.DBName;
import dashboard.db.DBType;
import dashboard.db.DBUtils;
import dashboard.utils.DateUtil;



/**
 * @author zhaoxiang 20150202
 * @since 1.0
 * @param <T>
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public abstract class AbstractBaseService<T> {
	
	protected Logger log = Argo.instance.getLogger(getClass());
	
	protected final DAOHelper daoHelper;

	protected final Class<T> entityClass;

	public AbstractBaseService(Class<T> clss) {
		entityClass = clss;
		daoHelper = getDaoHelper();
	}
	
	public AbstractBaseService() {
		Type genType = getClass().getGenericSuperclass();
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		entityClass = (Class) params[0];
		daoHelper = getDaoHelper();
	}


	protected  DAOHelper getDaoHelper() {
		String configPath;
		 if (entityClass.isAnnotationPresent(DBName.class)) {  
			 DBName dbName =  entityClass.getAnnotation(DBName.class);
			 configPath = dbName.value().getConfigPath();
		 }else {
			 configPath = DBType.db_data_bi.getConfigPath();
		}
		return DBUtils.getDAOHelper(configPath);
	}

	
	public int add(T dbEntity) {
		try {
			return (Integer) daoHelper.sql.insert(dbEntity);
		} catch (Exception e) {
			log.error("",e);
		}
		return 0;
	}

	public boolean delete(int id) {
		try {
			daoHelper.sql.deleteByID(entityClass, id);
			return true;
		} catch (Exception e) {
			log.error("",e);
		}
		return false;
	}

	private static final String deleteLogicl_sql = "state=0";

	public boolean close(int id) {
		try {
			daoHelper.sql.upateByID(entityClass, deleteLogicl_sql, id);
			return true;
		} catch (Exception e) {
			log.error("",e);
		}
		return false;
	}

	public boolean updateAll(T dbEntity) {
		try {
			daoHelper.sql.upateEntity(dbEntity);
			return true;
		} catch (Exception e) {
			log.error("",e);
		}
		return false;
	}

	public boolean updateModify(T dbEntity) {

		return false;
	}

	public T getByID(int id) {
		try {
			return (T) daoHelper.sql.get(entityClass, id);
		} catch (Exception e) {
			log.error("",e);
		}
		return null;
	}

	public List<T> getByIDs(Integer[] ids) {
		try {
			return daoHelper.sql.getListByIDS(entityClass, ids);
		} catch (Exception e) {
			log.error("",e);
		}
		return Collections.emptyList();
	}

	
	public List<T> getListByConditon(String tableSuffix, String columns, String condition, String orderBy) {
		try {
			return daoHelper.sql.getListByCustom(entityClass,tableSuffix, columns, condition, orderBy);
		} catch (Exception e) {
			log.error("",e);
		}
		return Collections.emptyList();
	}
	
	public List<T> getListByConditon( String columns, String condition, String orderBy) {
		try {
			return daoHelper.sql.getListByCustom(entityClass,null, columns, condition, orderBy);
		} catch (Exception e) {
			log.error("",e);
		}
		return Collections.emptyList();
	}

	public List<T> getListByPage(String tableSuffix, String condition, String columns, int page, int pageSize, String orderBy) {
		try {
			return daoHelper.sql.getListByPage(entityClass,tableSuffix, condition, columns, page, pageSize, orderBy);
		} catch (Exception e) {
			log.error("",e);
		}
		return Collections.emptyList();
	}
	public List<T> getListByPage(String condition, String columns, int page, int pageSize, String orderBy) {
		try {
			return daoHelper.sql.getListByPage(entityClass,null, condition, columns, page, pageSize, orderBy);
		} catch (Exception e) {
			log.error("",e);
		}
		return Collections.emptyList();
	}

	public String getMaxDate(){
		try {
			List<T> li = getListByConditon("max(stat_date) as stat_date",null, null);
			Object maxDate = FieldUtils.readField(li.get(0), "stat_date", true);
			
			Class dateFieldCls = FieldUtils.getField(entityClass, "stat_date", true).getType();
			if(dateFieldCls == java.lang.String.class)
				return maxDate.toString();
			else if(dateFieldCls == java.util.Date.class){
				return DateUtil.getStringDate((Date) maxDate, "yyyy-MM-dd");
			}
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		} catch (Exception e) {
			e.printStackTrace();
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		}
	}
    
	public String getMaxDateByTableSuffix(String tableSuffix){
		try {
			List<T> li = getListByConditon(tableSuffix,"max(stat_date) as stat_date",null, null);
			Object maxDate = FieldUtils.readField(li.get(0), "stat_date", true);
			
			Class dateFieldCls = FieldUtils.getField(entityClass, "stat_date", true).getType();
			if(dateFieldCls == java.lang.String.class)
				return maxDate.toString();
			else if(dateFieldCls == java.util.Date.class){
				return DateUtil.getStringDate((Date) maxDate, "yyyy-MM-dd");
			}
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		} catch (Exception e) {
			e.printStackTrace();
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		}
	}
	public String getMaxDate(String condition){
		try {
			List<T> li = getListByConditon("max(stat_date) as stat_date",condition, null);
			Object maxDate = FieldUtils.readField(li.get(0), "stat_date", true);
			
			Class dateFieldCls = FieldUtils.getField(entityClass, "stat_date", true).getType();
			if(dateFieldCls == java.lang.String.class)
				return maxDate.toString();
			else if(dateFieldCls == java.util.Date.class){
				return DateUtil.getStringDate((Date) maxDate, "yyyy-MM-dd");
			}
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		} catch (Exception e) {
			e.printStackTrace();
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		}
	}
	
	public String getMinDate(){
		try {
			List<T> li = getListByConditon("min(stat_date) as stat_date",null, null);
			Object maxDate = FieldUtils.readField(li.get(0), "stat_date", true);
			
			Class dateFieldCls = FieldUtils.getField(entityClass, "stat_date", true).getType();
			if(dateFieldCls == java.lang.String.class)
				return maxDate.toString();
			else if(dateFieldCls == java.util.Date.class){
				return DateUtil.getStringDate((Date) maxDate, "yyyy-MM-dd");
			}
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		} catch (Exception e) {
			e.printStackTrace();
			return DateUtil.getStringDate(new Date(), "yyyy-MM-dd");
		}
	}
	
}
